package org.vnl.platform.web.impl.myfaces.dojo.component.renderer;

import java.io.IOException;
import java.util.Map;

import javax.faces.component.UIComponent;
import javax.faces.component.UIOutput;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;

import org.apache.commons.lang3.StringUtils;
import org.vnl.platform.web.impl.myfaces.dojo.component.DojoAjaxForm;
import org.vnl.platform.web.impl.myfaces.dojo.component.DojoForm;


public class DojoAjaxFormRenderer extends DojoRendererBase {

    private static final String DOJO_TYPE = "dijit.form.Form";
    private static final String PREFIX = "VON_";
    
    @Override
    public void encodeBegin(FacesContext facesContext, UIComponent component) throws IOException {
        if (!(component instanceof DojoAjaxForm)) {
            return;
        }
        DojoAjaxForm form = (DojoAjaxForm) component;
        String clientId = form.getClientId(facesContext);
        String actionUrl = getActionURL(facesContext,component);
        ResponseWriter writer = facesContext.getResponseWriter();
        
        writer.startElement("form", form);
        writer.writeAttribute("id", clientId, null);
        writer.writeAttribute("name", clientId, null);
        writeDojoType(writer, DOJO_TYPE);
        writeDojoId(writer, form.getDojoId(), clientId);
        writeGeneralProperty(writer, "target", form.getTarget());
        writeGeneralProperty(writer, "method", "post");
        writeGeneralProperty(writer, "enctype", "application/x-www-form-urlencoded");
        writeGeneralProperty(writer, "action", actionUrl);
        writeOnSubmit(writer, facesContext, form);
        writer.startElement("input", form);
        writeGeneralProperty(writer, "type", "hidden");
        writeGeneralProperty(writer, "name", PREFIX+form.getId());
        writeGeneralProperty(writer, "value", PREFIX+form.getId());
    }

    private void writeOnSubmit(ResponseWriter writer, FacesContext facesContext, DojoAjaxForm form) throws IOException {
        writer.startElement("script", form);
        writeGeneralProperty(writer, "type", "dojo/method");
        writeGeneralProperty(writer, "data-dojo-event", "onSubmit");
        StringBuffer sb = new StringBuffer();
        UIComponent facet = form.getFacet("onSubmit");
        if (facet != null) {
            if (facet instanceof UIOutput) {
                sb.append(((UIOutput) facet).getValue());
            }
        }
        sb.append("require([\"dojo/query\",\"dojo/_base/xhr\"], function(query, xhr) {");
        sb.append("vonAjaxSubmit = function(frm) {");
        sb.append("try {");
        sb.append("xhr.post({");
        sb.append("form: frm.domNode,");
        sb.append("load: function(response) {");
        sb.append("dojo.place(dojo.toDom(response),dojo.byId('");
        sb.append(form.getResultId());
        sb.append("'));");
        sb.append("},");
        sb.append("error: function(error) {");
        sb.append("}");
        sb.append("});");
        sb.append("}catch (err) {");
        sb.append("}");
        sb.append("return false;");
        sb.append("};");
        sb.append("});");
        sb.append("return vonAjaxSubmit(this);");
        writer.write(sb.toString());
        writer.endElement("script");
    }

    private String getActionURL(FacesContext facesContext, UIComponent component) {
        String viewId = facesContext.getViewRoot().getViewId();
        String actionURL = facesContext.getApplication().getViewHandler().getActionURL(facesContext, viewId);
        return facesContext.getExternalContext().encodeActionURL(actionURL);
    }

    @Override
    public void decode(FacesContext context, UIComponent component) {
        if (!(component instanceof DojoForm)) {
            return;
        }
        DojoForm form = (DojoForm) component;
        Map<String, String> map = context.getExternalContext().getRequestParameterMap();
        if (map != null) {
            String str = map.get(PREFIX+form.getId());
            if (!StringUtils.isBlank(str)) {
                if (str.equals(PREFIX+form.getId())) {
                    form.setSubmitted(true);
                    return;
                }
            }
        }
        form.setSubmitted(false);
    }

    @Override
    public void encodeEnd(FacesContext context, UIComponent component) throws IOException {
        if (!(component instanceof DojoForm)) {
            return;
        }
        ResponseWriter rw = context.getResponseWriter();
        context.getApplication().getViewHandler().writeState(context);
        rw.endElement("form");
    }

}
